<?php
// +----------------------------------------------------------------------
// | PHP [ JUST YOU ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2017 http://www.jyphp.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: FlyingPig <flyingpigfp@163.com>
// +----------------------------------------------------------------------

namespace App\Logic;


use App\Common\Logger;
use App\Exceptions\ApiException;
use App\Model\QuicklyGrab\PrizeList;
use App\Model\QuicklyGrab\Rec;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class QuicklyGrabLogic extends Logic
{

    //第几次购买,就扣第几次的钻石
    protected static $diamond = [0 => 50, 1 => 50, 2 => 100, 3 => 100, 4 => 150];

    public function exchangeTicketLogic($is_return_two_buy = true, $uid)
    {
        //获取当前会员VIP信息
        $vip = $this->getVip($uid);
        //当前用户会员可购买的次数
        $prepaid_number = $vip['buy_number'];
        //当前用户会员等级
        $user_level = $vip['level'];
        //刷新快抢赛的基本次数和本日充值次数
        $this->ticketLogic($uid, false);

        $object = DB::table('t_quickly_grab_ticket_info')->where('date', date('Y-m-d'))->where('uid', $uid)->first(['charge_count', 'count']);

        DB::beginTransaction();
        try {
            //校验是否已经超出当天的购买次数
            $this->checkBuyCount($object->charge_count, $prepaid_number, $user_level);
            //如果是会员并且是第二次购买,返回相应的文案提示
            $this->twoBuy($is_return_two_buy, $user_level, $object->charge_count);
            //校验兑换的钻石数量
            $number = $this->exchangeNumber($user_level, $uid, $object->charge_count);
            //开始兑换
            $this->exchange($uid, $number);
            DB::commit();
            return ['front_count' => $object->count, 'later_count' => DB::table('t_quickly_grab_ticket_info')->where('date', date('Y-m-d'))->where('uid', $uid)->value('count')];
        } catch (\ Exception $exception) {
            DB::rollBack();
            Logger::instance()->setErrorLog($exception);
        }
    }


    public function ticketLogic($uid, $is_return = true)
    {
        $vip = $this->getVip($uid);
        if ($this->insertOrUpdateTicketInfo($uid)) {
            DB::table('t_quickly_grab_ticket_info')->where('uid', $uid)->update(['count' => $vip['give_number'], 'vip_level' => $vip['level']]);
        }
        if ($is_return) {
            $object = DB::table('t_quickly_grab_ticket_info')->where('uid', $uid)->first();
            if ($object->charge_count >= $vip['buy_number']) {
                $next_recharge = -1;
            } else {
                $next_recharge = empty(self::$diamond[$object->charge_count]) ? -1 : self::$diamond[$object->charge_count];
            }
            return [
                'total_charge_count' => $vip['buy_number'],
                'charge_count' => $object->charge_count,
                'surplus_charge_count' => $vip['buy_number'] - $object->charge_count,
                'next_recharge' => $next_recharge,
                'count' => $object->count
            ];
        }
    }


    public function prize($limit)
    {
        $redis_list = Redis::get('QUICKLY_GRAB_PRIZE_LIST');
        if (!empty($redis_list)) {
            return json_decode($redis_list, true);
        }
        $list = PrizeList::where('uid', '>', 0)
            ->where('status', 1)
            ->where('reward_type', 1)
            ->orderBy('update_time', 'desc')
            ->limit($limit)
            ->get(['uid', 'match_id']);
        if (!empty($list)) {
            Redis::set('QUICKLY_GRAB_PRIZE_LIST', json_encode($list));
            Redis::expire('QUICKLY_GRAB_PRIZE_LIST', 60);
        }
        $list = $list->isEmpty() ? '' : $list;
        return $list;
    }


    public function recLogic($id)
    {
        $object = Rec::where('id', $id)->first();
        if (empty($object)) {
            return '';
        }
        $uid_arr = [];
        if (!empty($object->members)) {
            $uid_arr = explode('|', $object->members);
        }
        array_push($uid_arr, $object->winner);
        $user_list         = DB::table('t_player_info')->whereIn('id', $uid_arr)->get(['id', 'nick_name'])->map(function ($value) use ($object) {
            if ($value->id == $object->winner) {
                $value->is_winner = 1;
            } else {
                $value->is_winner = 0;
            }
            return $value;
        });
        $object->user_list = $user_list;
        return $object;
    }


    private function insertOrUpdateTicketInfo($uid)
    {
        DB::beginTransaction();
        try {
            if (empty(DB::table('t_quickly_grab_ticket_info')->where('uid', $uid)->lockForUpdate()->value('uid'))) {
                $result = DB::table('t_quickly_grab_ticket_info')->insert([
                    'uid' => $uid,
                    'count' => 0,
                    'date' => date('Y-m-d'),
                ]);
            } else {
                $result = DB::table('t_quickly_grab_ticket_info')
                    ->where('date', '<>', date('Y-m-d'))
                    ->where('uid', $uid)
                    ->update(['count' => 0, 'date' => date('Y-m-d'), 'charge_count' => 0, 'vip_level' => 0]);
            }
            DB::commit();
            return $result ? true : false;
        } catch (\Exception $exception) {
            DB::rollBack();
            throw new ApiException('刷新门票失败', $exception);
        }
    }


    private function checkBuyCount($charge_count, $prepaid_number, $level)
    {
        if ($charge_count >= $prepaid_number) {
            //普通会员
            if ($level == 0) {
                throw new ApiException('哦豁~您的快去次数不足！成为会员即可领取更多快抢机会，享受更多福利');
            }
            //其它会员
            throw new ApiException('哦豁~您的快抢赛次数不足！适度游戏，健康快抢，请明日再来！');
        }
    }


    private function exchangeNumber($user_level, $uid, $charge_count)
    {
        //第几次购买,就扣第几次的钻石
        $number = self::$diamond[$charge_count];
        if ($user_level == 0) {
            $number = 50;
        }
        if (!DB::table('t_player_info')->where('id', $uid)->where('diamonds', '>=', $number)->lockForUpdate()->value('id')) {
            throw new ApiException('钻石数量不足,请充值');
        }
        return $number;
    }


    private function exchange($uid, $number)
    {
        if (!DB::table('t_player_info')->where('id', $uid)->update(['diamonds' => DB::raw("diamonds - $number")])) {
            throw new ApiException('扣除钻石失败');
        }
        if (!DB::table('t_quickly_grab_ticket_info')->where('uid', $uid)->update([
            'charge_count' => DB::raw("charge_count + 1"),
            'count' => DB::raw("count + 2"),
        ])) {
            throw new ApiException('增加基本次数失败');
        }
        DB::table('t_user_diamonds_rec')->insert([
            'uid' => $uid,
            'num' => -$number,
            'source' => '钻石兑换快抢赛基本次数',
            'comment' => 'diamonds:' . $number . '--count:2'
        ]);
    }


    private function twoBuy($is_return_two_buy, $user_level, $charge_count)
    {
        if ($is_return_two_buy && $user_level > 0) {
            if ($charge_count > 0) {
                throw new ApiException(
                    '哦豁~您的快抢赛次数不足！今日第' . ($charge_count + 1) . '次兑换额外次数，是否消耗' . self::$diamond[$charge_count] . '钻石兑换2次快抢赛次数？'
                    , -1);
            }
        }
    }


    private function getVip($uid)
    {
        $object = DB::table('t_vip_conf')->where('id', function ($query) use ($uid) {
            $query->from('t_vip_info')
                ->where('uid', $uid)
                ->where('expire_time', '>', date('Y-m-d H:i:s'))
                ->where('status', 1)
                ->select(['vip_conf_id']);
        })->first(['buy_number', 'level', 'give_number']);
        if (empty($object)) {
            return ['level' => 0, 'buy_number' => 1, 'give_number' => 1];
        }
        return ['level' => $object->level, 'buy_number' => $object->buy_number, 'give_number' => $object->give_number];
    }


    //需要判断快抢赛表是否有数据,有数据就直接更新
    //否侧就直接更新次数 1(普通用户送的次数)+送的快抢赛次数
    public function updateOrInsertCount($uid,$num)
    {
        $object = DB::table('t_quickly_grab_ticket_info')->where('uid', $uid)->first();
        if ($object) {
            if ($object->date == date('Y-m-d')) {
                $count = $object->count + $num;
            } else {
                $count = 1 + $num;
            }
            DB::table('t_quickly_grab_ticket_info')->where('uid', $uid)->update(['count' => $count]);
        } else {
            $count = 1 + $num;
            DB::table('t_quickly_grab_ticket_info')->insert([
                'uid' => $uid,
                'count' => $count,
                'date' => date('Y-m-d')
            ]);
        }
    }

}